Spring Cloud 게 이 트 웨 이 서비스 zuul  동적 경로 의 실현 방법

zuul 동적 경로
게 이 트 웨 이 서 비 스 는 데이터 의 유일한 입구 이다.함부로 서 비 스 를 멈 출 수 없다.그래서 동태 적 인 경로 가 특히 필요 하 다.
데이터베이스 동적 루트 는 이벤트 리 셋 메커니즘 을 바탕 으로 zuul 의 루트 속성 을 수정 합 니 다.
DiscoveryClientRouteLocator

Discovery Client RouteLocator 는 기본 새로 고침 의 핵심 처리 클래스 임 을 볼 수 있 습 니 다.

//           protected  。         。
protected LinkedHashMap<String, ZuulRoute> locateRoutes()

//        RefreshableRouteLocator   
 public void refresh() {
   this.doRefresh();
 }
이 두 가지 방법 은 모두 Simple RouteLocator 류 를 계승 하고 재 작업 한 것 이다.사실 공식 적 인 방법 설명 이 있 습 니 다.로드 맵 관 계 를 동적 으로 읽 어야 한다 면.하위 클래스 가 이 두 가지 방법 을 다시 써 야 한다.
구체 적 인 실현 을 진행 하 다
우선 pom jar 패키지 가 져 오기 my sql 데이터 베 이 스 를 연결 해 야 합 니 다.  

<dependency>
   <groupId>mysql</groupId>
   <artifactId>mysql-connector-java</artifactId>
  </dependency>

  <!-- jdbc -->
  <dependency>
   <groupId>org.springframework.boot</groupId>
   <artifactId>spring-boot-starter-jdbc</artifactId>
  </dependency>
루트 실체 ZuulRouteEntity

package com.xian.cloud.entity;

import lombok.Data;

import java.io.Serializable;
import java.util.Date;

/**
 * <Description>      
 *
 * @author [email protected]
 * @version 1.0
 * @createDate 2019/10/30 15:00
 */
@Data
public class ZuulRouteEntity implements Serializable {
 private static final long serialVersionUID = 1L;

 /**
  * router Id
  */
 private Integer id;
 /**
  *     
  */
 private String path;
 /**
  *     
  */
 private String serviceId;
 /**
  * url  
  */
 private String url;
 /**
  *       
  */
 private String stripPrefix;
 /**
  *     
  */
 private String retryable;
 /**
  *     
  */
 private String enabled;
 /**
  *      
  */
 private String sensitiveheadersList;
 /**
  *     
  */
 private Date createTime;
 /**
  *     
  */
 private Date updateTime;
 /**
  *     (0-  ,1-  )
  */
 private String delFlag;
}

새 Discovery RouteLocator 클래스 의 부모 인터페이스 가 변 하지 않 습 니 다.

package com.xian.cloud.router;


import com.google.common.base.Strings;
import com.google.common.collect.Sets;
import com.xian.cloud.entity.ZuulRoute;
import lombok.extern.slf4j.Slf4j;
import org.springframework.cloud.netflix.zuul.filters.RefreshableRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.SimpleRouteLocator;
import org.springframework.cloud.netflix.zuul.filters.ZuulProperties;
import org.springframework.jdbc.core.BeanPropertyRowMapper;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.util.StringUtils;

import java.util.*;

/**
 * <Description>
 *
 * @author [email protected]
 * @version 1.0
 * @createDate 2019/10/30 18:57
 */
@Slf4j
public class DiscoveryRouteLocator extends SimpleRouteLocator implements RefreshableRouteLocator {

 private ZuulProperties properties;

 private JdbcTemplate jdbcTemplate;

 public DiscoveryRouteLocator(String servletPath, ZuulProperties properties, JdbcTemplate jdbcTemplate) {
  super(servletPath, properties);
  this.properties = properties;
  this.jdbcTemplate = jdbcTemplate;
  log.info("servletPath:{}",servletPath);
 }

 @Override
 public void refresh() {
  doRefresh();
 }

 @Override
 protected Map<String, ZuulProperties.ZuulRoute> locateRoutes() {
  LinkedHashMap<String, ZuulProperties.ZuulRoute> routesMap = new LinkedHashMap<String, ZuulProperties.ZuulRoute>();
  //            
  routesMap.putAll(super.locateRoutes());
  //         
  routesMap.putAll(getRouteList());
  //      
  LinkedHashMap<String, ZuulProperties.ZuulRoute> values = new LinkedHashMap<>();
  for (Map.Entry<String, ZuulProperties.ZuulRoute> entry : routesMap.entrySet()) {
   String path = entry.getKey();
   // Prepend with slash if not already present.
   if (!path.startsWith("/")) {
    path = "/" + path;
   }
   if (StringUtils.hasText(this.properties.getPrefix())) {
    path = this.properties.getPrefix() + path;
    if (!path.startsWith("/")) {
     path = "/" + path;
    }
   }
   values.put(path, entry.getValue());
  }
  return values;
 }

 /**
  *       zuul    
  * @return
  */
 private LinkedHashMap<String, ZuulProperties.ZuulRoute> getRouteList() {
  LinkedHashMap<String, ZuulProperties.ZuulRoute> zuulRoutes = new LinkedHashMap<>();
  List<ZuulRoute> sysZuulRoutes = jdbcTemplate.query("select * from sys_zuul_route where del_flag = 0", new BeanPropertyRowMapper<>(ZuulRoute.class));

  for (ZuulRoute route: sysZuulRoutes) {

   //     
   if (Strings.isNullOrEmpty(route.getPath()) && Strings.isNullOrEmpty(route.getUrl())) {
    continue;
   }

   ZuulProperties.ZuulRoute zuulRoute = new ZuulProperties.ZuulRoute();
   try {
    zuulRoute.setId(route.getServiceId());
    zuulRoute.setPath(route.getPath());
    zuulRoute.setServiceId(route.getServiceId());
    zuulRoute.setRetryable(Objects.equals("0", route.getRetryable()) ? Boolean.FALSE : Boolean.TRUE);
    zuulRoute.setStripPrefix(Objects.equals("0", route.getStripPrefix()) ? Boolean.FALSE : Boolean.TRUE);
    zuulRoute.setUrl(route.getUrl());
    List<String> sensitiveHeadersList = Arrays.asList(route.getSensitiveheadersList().split(","));
    if (sensitiveHeadersList != null) {
     Set<String> sensitiveHeaderSet = Sets.newHashSet();
     sensitiveHeadersList.forEach(sensitiveHeader -> sensitiveHeaderSet.add(sensitiveHeader));
     zuulRoute.setSensitiveHeaders(sensitiveHeaderSet);
     zuulRoute.setCustomSensitiveHeaders(true);
    }
   } catch (Exception e) {
    log.error("         ", e);
   }
   log.info("        ,path:{},serviceId:{}", zuulRoute.getPath(), zuulRoute.getServiceId());
   zuulRoutes.put(zuulRoute.getPath(), zuulRoute);

  }
  return zuulRoutes;
 }
}


우 리 는 또 하나의 사건 의 생산자 와 소비자 가 직접 그림 을 그 려 서 하나의 유형 에 편리 하 게 통합 시 켜 야 한다.

package com.xian.cloud.event;

import com.xian.cloud.router.DiscoveryRouteLocator;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.discovery.event.HeartbeatEvent;
import org.springframework.cloud.client.discovery.event.HeartbeatMonitor;
import org.springframework.cloud.context.scope.refresh.RefreshScopeRefreshedEvent;
import org.springframework.cloud.netflix.zuul.RoutesRefreshedEvent;
import org.springframework.cloud.netflix.zuul.web.ZuulHandlerMapping;
import org.springframework.context.ApplicationEvent;
import org.springframework.context.ApplicationEventPublisher;
import org.springframework.context.ApplicationListener;
import org.springframework.context.event.ContextRefreshedEvent;
import org.springframework.stereotype.Service;

/**
 * <Description>         ,      
 *
 * @author [email protected]
 * @version 1.0
 * @createDate 2019/10/30 15:27
 */
@Service
public class RefreshRouteService implements ApplicationListener<ApplicationEvent> {

 @Autowired
 private ZuulHandlerMapping zuulHandlerMapping;

 private HeartbeatMonitor heartbeatMonitor = new HeartbeatMonitor();

 @Autowired
 ApplicationEventPublisher publisher;

 @Autowired
 private DiscoveryRouteLocator dynamicRouteLocator;

 /**
  *          refreshRoute()         
  */
 public void refreshRoute() {
  RoutesRefreshedEvent routesRefreshedEvent = new RoutesRefreshedEvent(dynamicRouteLocator);
  publisher.publishEvent(routesRefreshedEvent);
 }

 /**
  *      。        
  * @param event
  */
 @Override
 public void onApplicationEvent(ApplicationEvent event) {
  if(event instanceof ContextRefreshedEvent || event instanceof RefreshScopeRefreshedEvent || event instanceof RoutesRefreshedEvent){
   //      。     ,      
   zuulHandlerMapping.setDirty(true);
  }else if(event instanceof HeartbeatEvent){
   //    ,       。        
   HeartbeatEvent heartbeatEvent = (HeartbeatEvent)event;
   if(heartbeatMonitor.update(heartbeatEvent.getValue())){
    zuulHandlerMapping.setDirty(true);
   }
  }
 }
}

대외 적 으로 트리거 인 터 페 이 스 를 제공 하 다.

package com.xian.cloud.controller;
import com.xian.cloud.event.RefreshRouteService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;
/**
 * <Description>         
 *
 * @author [email protected]
 * @version 1.0
 * @createDate 2019/10/30 20:23
 */
@RestController
public class RefreshController {
 @Autowired
 private RefreshRouteService refreshRouteService;
 @GetMapping("/refresh")
 public String refresh() {
  refreshRouteService.refreshRoute();
  return "refresh";
 }
}
데이터베이스 테이블 구조

CREATE TABLE `sys_zuul_route` (
 `id` int(11) NOT NULL AUTO_INCREMENT COMMENT 'router Id',
 `path` varchar(255) NOT NULL COMMENT '    ',
 `service_id` varchar(255) NOT NULL COMMENT '    ',
 `url` varchar(255) DEFAULT NULL COMMENT 'url  ',
 `strip_prefix` char(1) DEFAULT '1' COMMENT '      ',
 `retryable` char(1) DEFAULT '1' COMMENT '    ',
 `enabled` char(1) DEFAULT '1' COMMENT '    ',
 `sensitiveHeaders_list` varchar(255) DEFAULT NULL COMMENT '     ',
 `create_time` timestamp NULL DEFAULT CURRENT_TIMESTAMP COMMENT '    ',
 `update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '    ',
 `del_flag` char(1) DEFAULT '0' COMMENT '    (0-  ,1-  )',
 PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=9 DEFAULT CHARSET=utf8mb4 ROW_FORMAT=DYNAMIC COMMENT='       '

프로필 client 소비자 서비스 루트 설정 설명 을 삭제 합 니 다.데이터 원본 설정.데이터베이스 에서 읽 기

시작 서비스 인쇄 로그
2019-10-30 20:49:39.946  INFO 63449 --- [TaskScheduler-1] c.xian.cloud.router.DynamicRouteLocator  : 데이터베이스 사용자 정의 경로 설정 추가,path:/client/*,serviceId:cloud-discovery-client
2019-10-30 20:49:40.397  INFO 63449 --- [TaskScheduler-1] c.xian.cloud.router.DynamicRouteLocator  : 데이터베이스 사용자 정의 경로 설정 추가,path:/client/*,serviceId:cloud-discovery-client
postman 클 라 이언 트 인터페이스 요청 전송 성공 여부

zuul 동적 게 이 트 웨 이 경로 기반 완료.
총결산
위 에서 말 한 것 은 편집장 이 소개 한 Spring Cloud 게 이 트 웨 이 서비스 zuul 입 니 다.  동적 경로 의 실현 방법 은 여러분 에 게 도움 이 되 기 를 바 랍 니 다.만약 에 궁금 한 점 이 있 으 면 저 에 게 메 시 지 를 남 겨 주세요.편집장 은 신속하게 여러분 에 게 대답 할 것 입 니 다.여기 서도 저희 사이트 에 대한 여러분 의 지지 에 감 사 드 립 니 다!
만약 당신 이 본문 이 당신 에 게 도움 이 된다 고 생각한다 면,전 재 를 환영 합 니 다.번 거 로 우 시 겠 지만 출처 를 밝 혀 주 십시오.감사합니다!

좋은 웹페이지 즐겨찾기